home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / games / dcgames4.zip / FIGHTING.SCR < prev    next >
Text File  |  1995-10-04  |  9KB  |  295 lines

  1.  
  2. !------------------------------------------------------
  3. ! Monster control script !
  4. !
  5. ! When a fight starts, entry point 0 is invoked to 
  6. ! spread out the monster group, and then entry point 1
  7. ! is invoked to allow each of the monsters to move
  8. ! during the fight itself.
  9. !------------------------------------------------------
  10.  
  11. !
  12. ! = = = Position Monsters = = =
  13. !
  14. ! When this entry point is invoked, the first NPC
  15. ! is the leader, and the rest of the NPCs (if any)
  16. ! are followers and have:
  17. !  a) Half the stats (hp, str, aim, etc.) of the first one
  18. !  b) The graphics block from NPC.BLOCK2
  19. !  c) The name associated with the graphics block (not the 
  20. !     first NPC's name.
  21. !  d) All occupy the same exact X/Y position
  22. !
  23. ! What is left to do is to position them in an
  24. ! intelligent manner for the fight.
  25. !
  26.  
  27. :@0
  28.  
  29.   if not fighting then
  30.     writeln( "BUG: FIGHTING script called when not fighting! " );
  31.     stop;
  32.   endif;
  33.  
  34.   L0 = sgn( npc.x - player.x );
  35.   if L0 = 0  then L0 = -1; endif;
  36.   L1 = sgn( npc.y - player.y );
  37.   if L1 = 0  then L1 =  1; endif;
  38.   L2 =  0;
  39.   L4 = L0; ! Start Here !
  40.   L5 =  0; 
  41.   foreach NPC do
  42.     if npc.index > 0 then   ! A follower !
  43.       :AGAIN
  44.         inc(L2);
  45.         if L2 > 32 then
  46.           stop;  ! Give Up. Leave all other NPCs where they are !
  47.         endif;
  48.         gosub CHK_POS;
  49.         if L5 <> L1 then
  50.           inc( L5, L1 );
  51.         else
  52.           L5 = 0;
  53.           dec( L4, L0 );
  54.           if L4 = 0 then
  55.             inc( L0, sgn(L0) );
  56.             inc( L1, sgn(L1) );
  57.             L4 = L0;
  58.           endif;
  59.         endif;
  60.       if npc.x <> L11 or npc.y <> L12 goto :AGAIN;
  61.     endif;
  62.     :NEXTONE
  63.   endfor;
  64.   stop;
  65.  
  66. :CHK_POS
  67.   L11 = npc.x + L4;
  68.   L12 = npc.y + L5;
  69.   if L11 < 0 or L12 < 0 or L11 >= world.x or L12 >= world.y then
  70.     return;
  71.   endif;
  72.   foreach player do
  73.     if player.x = L11 and player.y = L12 then
  74.       return;
  75.     endif;
  76.   endfor;
  77.   L10 = world.density(L11,L12);
  78.   if npc.class = WATER_MONSTER then
  79.     if L10 = LOW_WATER or L10 = ROUGH_WATER or L10 = DEEP_WATER then
  80.       npc.x = L11;  npc.y = L12;
  81.     endif;
  82.   elsif npc.class = SPOOK_MONSTER then
  83.     if L10 <> LOW_WATER and L10 <> ROUGH_WATER and L10 <> DEEP_WATER then
  84.       npc.x = L11; npc.y = L12;
  85.     endif;
  86.   else
  87.     ! LAND and CAVE types
  88.     if L10 =  FLAT or L10 = ROUGH or L10 = VERY_ROUGH or
  89.        L10 = SWAMP or L10 = DESERT or L10 = SNOW then
  90.       npc.x = L11; npc.y = L12;
  91.     endif;
  92.   endif;
  93.   return;
  94.  
  95. !
  96. ! = = = Move Monsters = = =
  97. !
  98. :@1
  99.  
  100.   if not fighting then
  101.     writeln( "BUG: FIGHTING script called when not fighting! " );
  102.     stop;
  103.   endif;
  104.  
  105.   !
  106.   ! Now handle each monster, one at a time
  107.   !
  108.   foreach NPC do
  109.     frame( npc.x, npc.y, SYS_FRAME );
  110.     stats( npc );
  111.     write( npc.name );
  112.     if npc.hp = 1 then
  113.       writeln( " is unconscious.." );
  114.     elsif npc.paralyzed then
  115.       writeln( " is paralyzed.." );
  116.       dec( npc.paralyzed );
  117.     elsif npc.scared then
  118.       writeln( " is scared stiff.." );
  119.       dec( npc.scared );
  120.     elsif npc.confused then
  121.       writeln( " is confused.." );
  122.       dec( npc.confused );
  123.     else
  124.       ! Setup...
  125.       if npc.weapon.count then 
  126.         L4 = npc.weapon.class;
  127.         L5 = npc.weapon.range;
  128.         L6 = npc.weapon.ammoneeded;
  129.         L7 = npc.weapon.damage;
  130.       else
  131.         L4 = BLUNT;
  132.         L5 = 1;
  133.         L6 = 0;
  134.         L7 = 1;
  135.       endif;
  136.       if L4 = MISSILE then
  137.         for L10 = 0 to 15 do
  138.           setbp( npc, L10 );
  139.           if npc.bp.count then
  140.             if npc.bp.type = AMMO and npc.bp.ammotype = L6 then
  141.               if npc.bp.count < 255 then
  142.                 ! Count of 255 means you never run out !
  143.                 dec(npc.bp.count);
  144.               endif;
  145.               L5 = max( L5, npc.bp.range ); ! Use ammo's range if higher !
  146.               inc( L7, npc.bp.damage );     ! If ammunition causes extra damage !
  147.               L6 = npc.bp.index;            ! Keep AMMO's BP here !
  148.               goto FOUND_AMMO;
  149.             endif;
  150.           endif;
  151.         endfor;
  152.         L4 = BLUNT;
  153.         L5 = 1;
  154.         L6 = 0;
  155.         L7 = 1;
  156.         :FOUND_AMMO
  157.       endif;
  158.  
  159.       ! For contact weapons, STRENGTH adjusts damage estimate !
  160.       if L4 = BLUNT or L4 = EDGED then
  161.         inc( L7, adjustments( npc.str ) );
  162.       endif;
  163.  
  164.       !
  165.       ! We have a weapon and a range, now find a player..
  166.       !
  167.       L1 =  -1;
  168.       L2 = 999;
  169.       foreach player do
  170.         if player.hp > 0 then
  171.           ! Distance to this player
  172.           L3 = max(abs(player.x - npc.x),abs(player.y - npc.y));
  173.           ! Find the closest player, in case all are too far away.
  174.           if L3 < L2 then
  175.             L2 = L3; L1 = player.index;
  176.           endif;
  177.           if L3 <= L5 then ! Found one close enough !
  178.             ! For MISSILE weapons, hit 50% adjusted by AIM
  179.             if L4 = MISSILE then
  180.               ! For missile weapon, hit 5 out of 10, adjusted by AIM !
  181.               if random( 10 ) + adjustments( npc.aim ) < 5 then
  182.                 writeln( " missed.." );
  183.                 voice( "BadAim", 1000 );
  184.                 goto NEXT_MONSTER;
  185.               else
  186.                 goto HIT_PLAYER;
  187.               endif;
  188.             else
  189.               ! For NON-MISSILE weapons, hit 70% adjusted up by
  190.               ! the NPCs dexerity and down by the PLAYER's.
  191.               if random(10) +
  192.                 adjustments(npc.dex) -
  193.                 adjustments(player.dex) < 3 then
  194.                 writeln( " missed.." );
  195.                 voice( "Swish", 1000 );
  196.                 goto NEXT_MONSTER;
  197.               else
  198.                 goto HIT_PLAYER;
  199.               endif;
  200.             endif;
  201.           endif;
  202.         endif;
  203.       endfor;
  204.  
  205.       ! 
  206.       ! None within range, move towards the closest one
  207.       !
  208.       s0 = " is blocked.";
  209.       if L1 >= 0 then
  210.  
  211.         ! Move one step towards the closest player (L1)
  212.         group.current = L1;
  213.         L1 = npc.x + sgn(player.x - npc.x);
  214.         L2 = npc.y + sgn(player.y - npc.y);
  215.  
  216.         ! Don't step on another player !
  217.         foreach player do
  218.           if player.x = L1 and player.y = L2 then
  219.             writeln( s0 );
  220.             goto NEXT_MONSTER;
  221.           endif;
  222.         endfor;
  223.         ! Or another monster 
  224.         L3 = npc.index; ! Save the NPC index !
  225.         foreach npc do
  226.           if npc.x = L1 and npc.y = L2 then
  227.             npc.index = L3; ! Restore the NPC index !
  228.             writeln( s0 );
  229.             goto NEXT_MONSTER;
  230.           endif;
  231.         endfor;
  232.         ! Ok to move...
  233.         npc.index = L3; ! Restore the NPC index !
  234. !
  235.         L3 = world.density(L1,L2);
  236.         if npc.class = WATER_MONSTER then
  237.           if L3 = LOW_WATER or L3 = ROUGH_WATER or L3 = DEEP_WATER then
  238.             npc.x = L1; npc.y = L2;
  239.             s0 = " moved.";
  240.           endif;
  241.         elsif npc.class = SPOOK_MONSTER then
  242.           if L3 <> LOW_WATER and L3 <> ROUGH_WATER and L3 <> DEEP_WATER then
  243.             npc.x = L1; npc.y = L2;
  244.             s0 = " moved.";
  245.           endif;
  246.         else
  247.           ! LAND and CAVE types
  248.           if L3 =  FLAT or L3 = ROUGH or L3 = VERY_ROUGH or
  249.              L3 = SWAMP or L3 = DESERT or L3 = SNOW then
  250.             npc.x = L1; npc.y = L2;
  251.             s0 = " moved.";
  252.           endif;
  253.         endif;        
  254.       endif;
  255.       writeln( s0 );
  256.       goto NEXT_MONSTER;
  257.  
  258. :HIT_PLAYER
  259.       if player.ac then ! Armor Class protects the PLAYER !
  260.         L8 = random( player.ac+1 ); ! Player's armor 
  261.         if L8 >= L7 then
  262.           writeln( " hits ", player.name, " but does not damage." );
  263.           voice( "Clank", 1000 );
  264.           goto NEXT_MONSTER;
  265.         endif;
  266.         dec( L7, L8 ); ! Reduce damage by L8 amount !
  267.       endif;
  268.       if player.hp > L7 then
  269.         writeln( " hits ", player.name, " for ", L7, " points of damage" );
  270.         dec( player.hp, L7 );
  271.         on random(3) goto :V1, :V2, :V3;
  272.        :V1 voice( "Argh",   1000 ); goto NEXT_MONSTER;
  273.        :V2 voice( "Ouch",   1000 ); goto NEXT_MONSTER;
  274.        :V3 voice( "Whoosh", 1000 ); goto NEXT_MONSTER;
  275.       else
  276.         voice( "Argh", 1000 );
  277.         write( " killed ", player.name, "!" );
  278.         L7 = player.hp;
  279.         player.hp = 0;
  280.       endif;       
  281.  
  282. :NEXT_MONSTER
  283.  
  284.     endif;
  285.     if sound then
  286.       wait(0); ! Wait for sounds to finish playing !
  287.       ! Note that wait(0) waits forever if sound is off !
  288.     endif;
  289.     wait(1); ! Now wait for one second to slow down !
  290.     frame( npc.x, npc.y, -SYS_FRAME );
  291.  
  292.   endfor;
  293.  
  294.   STOP;
  295.